package com.bravo.other.geoid;

import java.io.IOException;
import java.util.Map;

/**
 * Geoid Height Calculator Test Class
 * 
 * @author bravo
 */
public class GeoidHeightTest {
    
    public static void main(String[] args) {
        // Test coordinate point (Beijing Tiananmen)
        double latitude = 39.9042;
        double longitude = 116.4074;
        
        System.out.println("=== Geoid Height Calculation Test ===");
        System.out.printf("Test coordinates: Latitude %.4f°, Longitude %.4f°\n", latitude, longitude);
        System.out.println();
        
        // 1. Calculate using EGM2008 model
        try {
            double geoidHeightEGM2008 = GeoidHeightCalculator.calculateEGM2008(latitude, longitude);
            System.out.printf("EGM2008 model result: %.6f meters\n", geoidHeightEGM2008);
        } catch (Exception e) {
            System.err.println("EGM2008 model calculation failed: " + e.getMessage());
        }
        
        // 2. Calculate using EGM96 model
        try {
            double geoidHeightEGM96 = GeoidHeightCalculator.calculateEGM96(latitude, longitude);
            System.out.printf("EGM96 model result: %.6f meters\n", geoidHeightEGM96);
        } catch (Exception e) {
            System.err.println("EGM96 model calculation failed: " + e.getMessage());
        }
        
        // 3. Calculate using interpolation method
        try {
            Map<GeoidHeightCalculator.Coordinate, Double> controlPoints = 
                GeoidHeightCalculator.createSampleControlPoints();
            double geoidHeightInterpolation = GeoidHeightCalculator.calculateByInterpolation(
                latitude, longitude, controlPoints);
            System.out.printf("Interpolation method result: %.6f meters\n", geoidHeightInterpolation);
        } catch (Exception e) {
            System.err.println("Interpolation method calculation failed: " + e.getMessage());
        }
        
        // 4. Try online calculation (requires network connection)
        System.out.println();
        System.out.println("Trying online calculation (requires network connection)...");
        try {
            double geoidHeightOnline = GeoidHeightCalculator.calculateOnline(latitude, longitude);
            System.out.printf("Online service result: %.6f meters\n", geoidHeightOnline);
        } catch (IOException e) {
            System.err.println("Online calculation failed: " + e.getMessage());
            System.out.println("Note: Online calculation requires network connection and service may be unavailable");
        }
        
        // 5. Test geoid height for multiple cities
        System.out.println();
        System.out.println("=== Geoid Height Comparison for Multiple Cities ===");
        testMultipleCities();
        
        // 6. Accuracy analysis
        System.out.println();
        System.out.println("=== Accuracy Analysis ===");
        analyzeAccuracy();
    }
    
    /**
     * Test geoid height for multiple cities
     */
    private static void testMultipleCities() {
        // Define test city coordinates
        Object[][] cities = {
            {39.9042, 116.4074, "Beijing"},      // Beijing
            {31.2304, 121.4737, "Shanghai"},      // Shanghai
            {23.1291, 113.2644, "Guangzhou"},      // Guangzhou
            {30.2741, 120.1551, "Hangzhou"},      // Hangzhou
            {22.3193, 114.1694, "Shenzhen"},      // Shenzhen
            {29.8683, 121.5440, "Ningbo"},      // Ningbo
            {32.0603, 118.7969, "Nanjing"},      // Nanjing
            {36.6512, 117.1201, "Jinan"}       // Jinan
        };
        
        System.out.printf("%-10s %-12s %-12s %-12s\n", "City", "EGM2008", "EGM96", "Interpolation");
        System.out.println("------------------------------------------------");
        
        for (Object[] city : cities) {
            double lat = (Double) city[0];
            double lon = (Double) city[1];
            String name = (String) city[2];
            
            try {
                double egm2008 = GeoidHeightCalculator.calculateEGM2008(lat, lon);
                double egm96 = GeoidHeightCalculator.calculateEGM96(lat, lon);
                
                Map<GeoidHeightCalculator.Coordinate, Double> controlPoints = 
                    GeoidHeightCalculator.createSampleControlPoints();
                double interpolation = GeoidHeightCalculator.calculateByInterpolation(lat, lon, controlPoints);
                
                System.out.printf("%-10s %-12.6f %-12.6f %-12.6f\n", 
                    name, egm2008, egm96, interpolation);
                    
            } catch (Exception e) {
                System.out.printf("%-10s %-12s %-12s %-12s\n", 
                    name, "Failed", "Failed", "Failed");
            }
        }
    }
    
    /**
     * Accuracy analysis
     */
    private static void analyzeAccuracy() {
        System.out.println("Geoid Height Calculation Accuracy Description:");
        System.out.println("1. EGM2008 Model:");
        System.out.println("   - Accuracy: ±0.1-0.2 meters");
        System.out.println("   - Coverage: Global");
        System.out.println("   - Applications: High-precision measurement, scientific research");
        System.out.println();
        
        System.out.println("2. EGM96 Model:");
        System.out.println("   - Accuracy: ±0.5-1.0 meters");
        System.out.println("   - Coverage: Global");
        System.out.println("   - Applications: General engineering applications");
        System.out.println();
        
        System.out.println("3. Interpolation Method:");
        System.out.println("   - Accuracy: Depends on control point density and distribution");
        System.out.println("   - Coverage: Control point covered areas");
        System.out.println("   - Applications: Local areas, dense control point regions");
        System.out.println();
        
        System.out.println("4. Online Service:");
        System.out.println("   - Accuracy: Depends on service provider");
        System.out.println("   - Coverage: Service covered areas");
        System.out.println("   - Applications: Real-time calculation, no local model");
        System.out.println();
        
        System.out.println("Important Notes:");
        System.out.println("- Geoid height values are usually negative, indicating geoid is below ellipsoid");
        System.out.println("- Results from different models may vary, choose appropriate model based on application needs");
        System.out.println("- For high-precision applications, use EGM2008 or newer models");
        System.out.println("- In practice, consider model updates and data timeliness");
    }
}
